home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: grocery.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 09/18/1997
- // Date Last Modified: 03/18/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ------------- Program Description and Details ------------- //
- // ----------------------------------------------------------- //
- /*
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- This is a test program used to test the (P)ersistent base class
- in a practical database application.
- */
- // ----------------------------------------------------------- //
- #include "grocery.h"
- #include "strutil.h"
-
- Grocery::Grocery(POD *pod) : Persistent(pod)
- {
- name = "\0";
- brand = "\0";
- store = "\0";
- price = 0;
- quantity = 0;
- purchasing = 'N';
- line_total = 0;
- }
-
- Grocery::Grocery(const POD *pod) : Persistent(pod)
- {
- name = "\0";
- brand = "\0";
- store = "\0";
- price = 0;
- quantity = 0;
- purchasing = 'N';
- line_total = 0;
- }
-
- Grocery::Grocery()
- {
- name = "\0";
- brand = "\0";
- store = "\0";
- price = 0;
- quantity = 0;
- purchasing = 'N';
- line_total = 0;
- }
-
- unsigned Grocery::ObjectLength()
- {
- unsigned len = StringFileLength(name) + \
- StringFileLength(brand) + \
- StringFileLength(store) + \
- sizeof(price) + \
- sizeof(quantity) + \
- sizeof(purchasing) + \
- sizeof(line_total);
-
- return len;
- }
-
- FAU Grocery::Write()
- {
- ObjectHeader oh;
-
- FAU addr = pod->OpenDatabase()->Alloc(ObjectLength() + sizeof(ObjectHeader));
- if(!addr) return 0;
-
- oh.ClassID = GetClassID();
- oh.ObjectID = addr;
- WriteObjHeader(oh);
-
- WriteString(name);
- WriteString(brand);
- WriteString(store);
- pod->OpenDatabase()->Write(&price, sizeof(price));
- pod->OpenDatabase()->Write(&quantity, sizeof(quantity));
- pod->OpenDatabase()->Write(&purchasing, sizeof(purchasing));
- pod->OpenDatabase()->Write(&line_total, sizeof(line_total));
- objectaddress = addr;
-
- // Add the entry to the Index file
- if (UsingIndex()) {
- EntryKey key(name.c_str(), oh.ObjectID, oh.ClassID);
- AddKey(key);
- }
-
- return addr;
- }
-
- void Grocery::Read(FAU Address)
- {
- ObjectHeader oh;
-
- ReadObjHeader(oh, Address);
- if(oh.ClassID != GetClassID()) return; // Incorrect object type
-
- ReadString(name);
- ReadString(brand);
- ReadString(store);
- pod->OpenDatabase()->Read(&price, sizeof(price));
- pod->OpenDatabase()->Read(&quantity, sizeof(quantity));
- pod->OpenDatabase()->Read(&purchasing, sizeof(purchasing));
- pod->OpenDatabase()->Read(&line_total, sizeof(line_total));
- objectaddress = Address;
- }
-
- FAU Grocery::Find()
- {
- Grocery grocery;
-
- grocery.name = this->name;
- grocery.brand = this->brand;
- grocery.store = this->store;
- grocery.price = this->price;
- grocery.quantity = this->quantity;
- grocery.purchasing = this->purchasing;
- grocery.line_total = this->line_total;
-
- int rv; // Return value
-
- // Search the index file for this entry
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- rv = FindKey(e);
- if(rv) { // Found the object in the index file
- Read(e.object_address);
- return e.object_address;
- }
- else
- return 0;
- }
-
- FAU addr = 0;
- ObjectHeader oh;
-
- while(1)
- {
- addr = pod->OpenDatabase()->FindFirstObject(addr);
- if(!addr) break;
- ReadObjHeader(oh, addr);
- if(oh.ClassID == GetClassID()) {
- Read(addr);
- rv = CaseICmp(name, grocery.name);
- if(rv == 0) {
- objectaddress = addr;
- return addr; // Found unique data member
- }
- else {
- // Reset the objects data
- this->name = grocery.name;
- this->brand = grocery.brand;
- this->store = grocery.store;
- this->price = grocery.price;
- this->quantity = grocery.quantity;
- this->purchasing = grocery.purchasing;
- this->line_total = grocery.line_total;
- }
- }
- }
- return 0; // Could not find
- }
-
- void Grocery::Copy(const Grocery &ob)
- {
- name = ob.name;
- brand = ob.brand;
- store = ob.store;
- price = ob.price;
- quantity = ob.quantity;
- price = ob.price;
- purchasing = ob.purchasing;
- line_total = ob.line_total;
- }
-
- int Grocery::FullCompare(const Grocery &ob)
- {
- if(ob.name != name) return 0;
- if(ob.brand != brand) return 0;
- if(ob.store != store) return 0;
- if(ob.price != price) return 0;
- if(ob.quantity != quantity) return 0;
- if(ob.purchasing != purchasing) return 0;
- if(ob.line_total != line_total) return 0;
- return 1;
- }
-
- int operator==(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) == 0;
- }
-
- int operator!=(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) != 0;
- }
-
- int operator>(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) > 0;
- }
-
- int operator>=(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) >= 0;
- }
-
- int operator<(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) < 0;
- }
-
- int operator<=(const Grocery &a, const Grocery &b)
- {
- return CaseICmp(a.GetName(), b.GetName()) <= 0;
- }
-
- FAU Grocery::Delete()
- {
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- int rv = FindKey(e);
- if(rv) { // Found the object in the index file
- FAU addr = e.object_address;
- DeleteObject(e.object_address); // Delete from the data file
- RemoveKey(e); // Remove from the index file
- return addr;
- }
- else
- return 0; // Could not delete
- }
-
- FAU addr = Find();
- if(!addr) return 0; // Object does not exist
- DeleteObject(addr);
- return addr;
- }
-
- FAU Grocery::Remove()
- {
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- int rv = FindKey(e);
- if(rv) { // Found the object in the index file
- FAU addr = e.object_address;
- RemoveObject(e.object_address); // Remove from the data file
- RemoveKey(e); // Remove from the index file
- return addr;
- }
- else
- return 0; // Could not remove
- }
-
- FAU addr = Find();
- if(!addr) return 0; // Object does not exist
- RemoveObject(addr);
- return addr;
- }
-
- void Grocery::SaveChanges()
- // Will record any changes except for the object's variable
- // string members. All the other members have a fixed length
- // for which space has already has been allocated in the data
- // file. The objects address will remain the same in the data
- // file and the index file.
- {
- ObjectHeader oh;
- pod->OpenDatabase()->Seek(this->objectaddress);
- ReadObjHeader(oh);
- if(oh.ClassID != GetClassID()) return; // Incorrect object type
-
- ReadString(name);
- ReadString(brand);
- ReadString(store);
-
- Price pr = this->price;
- Quantity qt = this->quantity;
- Purchasing pur = this->purchasing;
- LineTotal lt = this->line_total;
-
- pod->OpenDatabase()->Write(&pr, sizeof(Price));
- pod->OpenDatabase()->Write(&qt, sizeof(Quantity));
- pod->OpenDatabase()->Write(&pur, sizeof(Purchasing));
- pod->OpenDatabase()->Write(<, sizeof(LineTotal));
- }
-
- int Grocery::CompareIndex()
- // Compares the data file to the index file.
- // Returns true if data and index file match.
- {
- if(!UsingIndex()) return 0;
-
- Grocery grocery(pod);
- EntryKey key;
-
- FAU oa; // Object Address
- VBHeader vb; // Variable Block Header
- ObjectHeader oh; // Object Header
-
- int objects = 0; // Keeps track of good variable blocks
- int matches = 0; // Keep track of matches
-
- FAU vbdfileEOF = pod->OpenDatabase()->GetEOF();
- FAU addr = 0;
- addr = pod->OpenDatabase()->FindFirstVB(addr); // Search the entire file
-
- if(addr == 0) { // No variable blocks found in file
- #ifdef CPP_EXCEPTIONS
- throw CNoObjectsExist();
- #else
- Error->SignalException(EHandler::NoObjectsExist, EHandler::DISPLAY);
- return 0;
- #endif
- }
-
- while(1) {
- if(addr >= vbdfileEOF) break;
- pod->OpenDatabase()->Read(&vb, sizeof(VBHeader), addr);
- if(vb.CkWord == CheckWord) {
- if((__SBYTE__)vb.Status == NormalVB) {
- oa = addr + sizeof(VBHeader);
- ReadObjHeader(oh, oa);
- if(oh.ClassID == GetClassID()) {
- objects++; // Increment the object count
- grocery.Read(oa);
- key.SetStrKey(grocery.GetName());
- key.SetOA(oa);
- key.SetCID(oh.ClassID);
- int rv = FindKey(key, 1);
- if(rv) matches++; // Index and data file match
- }
- }
- addr = addr + vb.Length; // Goto the next variable block
- }
- else {
- addr = pod->OpenDatabase()->VBSearch(addr);
- if(!addr) break;
- }
- }
-
- return objects == matches;
- }
-
- int Grocery::RebuildIndexFile(const char *fname)
- {
- if(!UsingIndex()) return 0;
-
- int rv; // (R)eturn (V)alue
- int CacheSize = 15;
-
- VBDFilePtr f(new VBDFile);
- Btree btx(CacheSize);
- f->Create(fname, sizeof(BtreeHeader));
- btx.Connect(f, 1);
-
- Grocery grocery(pod);
- EntryKey key;
-
- FAU oa; // Object Address
- VBHeader vb; // Variable Block Header
- ObjectHeader oh; // Object Header
-
- int objects = 0; // Keeps track of good variable blocks
- int inserts = 0; // Keep track of inserts
-
- FAU vbdfileEOF = pod->OpenDatabase()->GetEOF();
- FAU addr = 0;
- addr = pod->OpenDatabase()->FindFirstVB(addr); // Search the entire file
-
- if(addr == 0) { // No variable blocks found in file
- #ifdef CPP_EXCEPTIONS
- throw CNoObjectsExist();
- #else
- Error->SignalException(EHandler::NoObjectsExist, EHandler::DISPLAY);
- return 0;
- #endif
- }
-
- while(1) {
- if(addr >= vbdfileEOF) break;
- pod->OpenDatabase()->Read(&vb, sizeof(VBHeader), addr);
- if(vb.CkWord == CheckWord) {
- if((__SBYTE__)vb.Status == NormalVB) {
- oa = addr + sizeof(VBHeader);
- ReadObjHeader(oh, oa);
- if(oh.ClassID == GetClassID()) {
- objects++; // Increment the object count
- grocery.Read(oa);
- key.SetStrKey(grocery.GetName());
- key.SetOA(oa);
- key.SetCID(oh.ClassID);
- rv = btx.Add(key);
- if(!rv) {
- #ifdef CPP_EXCEPTIONS
- throw CAssertError();
- #else
- Error->SignalException(EHandler::AssertError);
- #endif
- }
- else
- inserts++; // Index and data file match
- }
- }
- addr = addr + vb.Length; // Goto the next variable block
- }
- else {
- addr = pod->OpenDatabase()->VBSearch(addr);
- if(!addr) break;
- }
- }
-
- return objects == inserts;
- }
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-